import * as THREE from 'three'
import { GridHelper, SphereGeometry, MeshBasicMaterial, Mesh, RepeatWrapping, BoxGeometry } from 'three'
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js'
import { ParametricGeometry } from 'three/examples/jsm/geometries/ParametricGeometry'
import Element from '../../base/Element'

export default class Skybox extends Element {
  constructor() {
    super()
    this.sky
    this.material
    this.init()
  }
  init() {
    this.createFloor()
    this.createSpotLight()
  }

  createFloor() {
    const planeFun = (u, v, position) => {
      const r = 200

      const x = Math.sin(u) * r
      const z = Math.sin(v / 2) * 2 * r
      const y = (Math.sin(u * 4 * Math.PI) + Math.cos(v * 2 * Math.PI)) * 0.2
      position.set(x, y, z)
      return new THREE.Vector3(x, y, z)
    }
    const geom = new ParametricGeometry(planeFun, 120, 160)
    const texture = this.resource.items['Skybox-FabricLeather']
    texture.wrapS = RepeatWrapping
    texture.wrapT = RepeatWrapping
    geom.computeBoundingBox()
    const xOffset = (geom.boundingBox.max.x - geom.boundingBox.min.x) / 2
    const yOffset = (geom.boundingBox.max.y - geom.boundingBox.min.y) / 2
    const zOffset = (geom.boundingBox.max.z - geom.boundingBox.min.z) / 2
    const material = new THREE.MeshLambertMaterial({
      name: '地板',
      color: 0xffffff,
      map: texture,
      side: THREE.DoubleSide,
    })
    this.floor = new THREE.Mesh(geom, material)
    this.floor.position.set(-xOffset, 0, -zOffset)
    this.scene.add(this.floor)
  }

  createSpotLight() {
    const spotLight = new THREE.SpotLight(0xffffff, 1, 500, Math.PI / 8, 0, 2)
    spotLight.position.set(40, 40, 40) //设置聚光灯的位置
    spotLight.target = this.floor
    this.scene.add(spotLight)
  }

  distoryObject(object3D, parent) {
    parent.remove(object3D)
    const children = object3D.children
    if (!children.length) {
      return
    }
    children.forEach(({ geometry, material, childrens }) => {
      geometry.dispose()
      if (Array.isArray(material)) {
        material.forEach((m) => m.dispose())
      } else {
        material?.dispose()
      }
      if (childrens && childrens.length) {
        childrens.forEach((item) => this.distoryObject(item, object3D))
      }
    })
  }

  update() {}
}
